|
Cytosim
PI
Cytoskeleton Simulator
|
A divide-and-conquer algorithm is used to find all segments of fibers close to a given point:
Such algortihm should lead to large CPU gain, if calling clear() or paintGrid() is limiting, which is the case in particular in 3D, because the number of grid-cells is large.
Public Types | |
| typedef Array< FiberLocus const * > | SegmentList |
| type for a list of FiberLocus | |
| typedef Grid< DIM, SegmentList, unsigned int > | grid_type |
Public Member Functions | |
| FiberGrid () | |
| creator | |
| virtual | ~FiberGrid () |
| destructor | |
| int | setGrid (const Space *, const Modulo *, real max_step, unsigned long max_nb_cells) |
| create a grid to cover the specified Space with cells of width max_step at most More... | |
| bool | hasGrid () const |
| true if the grid was initialized by calling setGrid() | |
| void | clear () |
| clear the grid | |
| void | paintGrid (const Fiber *first, const Fiber *last, real max_range) |
| paint the Fibers, to be able to find up to a distance max_range More... | |
| bool | tryToAttach (Vector const &, Hand &) const |
| given a position, find nearby Fiber segments and test attachement of the provided Hand More... | |
| SegmentList | nearbySegments (Vector const &P, real D, Fiber *exclude=0) |
| return all fiber segments located at a distance D or less from P, except those belonging to exclude More... | |
| FiberLocus | closestSegment (Vector const &) |
| return the closest Segment to the given position, if it is closer than gridRange | |
| void | testAttach (FILE *, Vector place, Fiber *start, HandProp const *) |
| test the results of tryToAttach(), at a particular position More... | |
| FiberGrid::SegmentList nearbySegments | ( | Vector const & | place, |
| real | D, | ||
| Fiber * | exclude = 0 |
||
| ) |
This function is limited to the range given in paintGrid();
paintGrid( first_fiber, last_fiber, max_range ) links all segments found in 'fiber' and its descendant, in the point-list GP that match distance(GP, segment) < H.
'H' is calculated such that tryToAttach() finds any segment closer than 'max_range':
To determine H, we start from a relation on the sides of a triangle: (A) distance( GP, segment ) < distance( GP, X ) + distance( X, segment ) where GP (grid-point) is the closest point on the grid to X.
Since GP in tryToAttach() is the closest point on mGrid to X, we have: (B) distance( GP, X ) < 0.5 * mGrid.diagonalLength()
Thus to find all rods for which: (B) distance( X, segment ) < max_range we simply use: H = max_range + 0.5 * mGrid.diagonalLength();
Note: H is calculated by paintGrid(), and the user only provides 'max_range'.
Linking all segments is done in an inverse way: for each segment, we cover all points of the grid inside a volume obtained by inflating the segment by the length H. We use for that the raterizer which calls the function paint() above.
Creates a grid where the dimensions of the cells are max_step at most. If the numbers of cells that need to be created is greater than max_nb_cells, the function returns 1 without building the grid. The return value is zero in case of success.
The algorithm works with any value of max_step (the results are always correct), but max_steps affects the efficiency (speed) of the algorithm: -if max_step is too slow, paintGrid() will be slow, -if max_step is too large, tryToAttach() will be slow. A good compromise is to set max_step equivalent to the attachment distance, or at least to the size of the segments of the Fibers.
Function testAttach() is given a position in space, it calls tryToAttach() from this position to check that:
The range at which Hand will the the Fibers is limited to the range given in paintGrid()